package com.hengshan.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hengshan.common.enums.RedisKey;
import com.hengshan.common.utils.BeanCopyUtil;
import com.hengshan.common.utils.RedisUtil;
import com.hengshan.domain.entity.Article;
import com.hengshan.domain.entity.Category;
import com.hengshan.domain.vo.ArticleVo;
import com.hengshan.domain.vo.PageVo;
import com.hengshan.mapper.ArticleMapper;
import com.hengshan.mapper.CategoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 文章表(Article)表服务实现类
 *
 * @author muxijun
 * @since 2023-10-19 12:04:07
 */
@Service("articleService")
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> {

    // 正式文章
    private static final int ARTICLE_STATUS_ON = 1;

    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 热门文章
     *
     * @return 热门文章列表
     */
    public List<Article> hotArticle() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Article::getId, Article::getTitle, Article::getViewCount)
                .eq(Article::getStatus, ARTICLE_STATUS_ON)
                .orderByDesc(Article::getViewCount);
        Page<Article> page = new Page<>(1, 10);
        page(page, queryWrapper);
        List<Article> list = page.getRecords();
        return list;
    }

    /**
     * 文章列表
     *
     * @param pageNum    第几页
     * @param pageSize   每页条数
     * @param categoryId 文章类别id
     * @return 所有文章列表
     */
    public PageVo<ArticleVo> getList(int pageNum, int pageSize, int categoryId) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Article::getId, Article::getTitle, Article::getSummary, Article::getCategoryId,
                        Article::getViewCount, Article::getThumbnail, Article::getCreateTime)
                .eq(Article::getStatus, ARTICLE_STATUS_ON)
                .eq(categoryId != 0, Article::getCategoryId, categoryId);
        Page<Article> page = new Page<>(pageNum, pageSize);
        page(page, queryWrapper);
        List<ArticleVo> articleVos = BeanCopyUtil.copyBeanList(page.getRecords(), ArticleVo.class);
        List<Category> categoryList = categoryMapper.selectList(null);
        for (ArticleVo a : articleVos) {
            String categoryName = categoryList.stream().filter(c -> c.getId() == a.getCategoryId()).findFirst().get().getName();
            a.setCategoryName(categoryName);
        }
        PageVo<ArticleVo> pageVo = new PageVo<>(articleVos, page.getTotal());
        return pageVo;
    }

    /**
     * 文章详情
     *
     * @param id 文章id
     * @return 文章详情
     */
    public ArticleVo getOneById(Integer id) {
        Article article = getById(id);
        Integer viewCount = RedisUtil.getMapValue(RedisKey.ARTICLE_VIEW_COUNT, id.toString());
        article.setViewCount(viewCount);
        ArticleVo articleVo = BeanCopyUtil.copyBean(article, ArticleVo.class);
        Category category = categoryMapper.selectById(article.getCategoryId());
        if (category != null) {
            articleVo.setCategoryName(category.getName());
        }
        return articleVo;
    }

    /**
     * 更新文章浏览量
     *
     * @param id 文章id
     */
    public void updateViewCount(Integer id) {
        //更新redis中对应id的浏览量
        RedisUtil.incrementMapValue(RedisKey.ARTICLE_VIEW_COUNT, id.toString(), 1);
    }

    @Transactional
    public boolean deleteByIds(List<Integer> ids) {
        return removeBatchByIds(ids);
    }

    @Transactional
    public boolean deleteById(Integer id) {
        return removeById(id);
    }

    @Transactional
    public Article update(Article article) {
        updateById(article);
        return article;
    }

    @Transactional
    public Article add(Article article) {
        save(article);
        return getById(article.getId());
    }

}

